﻿namespace Softserve.Pottery.Infrastructure
{
    using System;
    using System.Linq;
    using System.Collections.Generic;

    public interface IStorageController : IDisposable
    {
        /// <summary>
        /// Name of connected storage
        /// </summary>
        string GetStorageName<T>() where T : class;

        /// <summary>
        /// Indicates that storage are initialize
        /// </summary>
        bool IsInitialized<T>() where T : class;

        /// <summary>
        /// Initializes an new instance of Storage
        /// </summary>
        /// <param name="tableName"></param>
        void Initialize<T>(string connectionString) where T : class;

        /// <summary>
        /// Adds new entity to the storage
        /// </summary>
        /// <param name="tableEntity">Entity</param>
        /// <exception cref="ArgumentNullException">Fires if entity is null</exception>
        /// <exception cref="InvalidOperationException">Fires if Entity was not initialized</exception>
        void Add<T>(T tableEntity) where T : class;

        /// <summary>
        /// Updates some enyity
        /// </summary>
        /// <param name="tableEntity">Entity</param>
        /// <exception cref="ArgumentNullException">Fires if entity is null</exception>
        /// <exception cref="InvalidOperationException">Fires if Entity was not initialized</exception>
        void Update<T>(T tableEntity) where T : class;

        /// <summary>
        /// Deletes entity
        /// </summary>
        /// <param name="tableEntity">Entity</param>
        /// <exception cref="ArgumentNullException">Fires if entity is null</exception>
        /// <exception cref="InvalidOperationException">Fires if Entity was not initialized</exception>
        void Delete<T>(T tableEntity) where T : class;

        /// <summary>
        /// Creates new out of context instance of asked type
        /// </summary>
        /// <typeparam name="T">Asked type</typeparam>
        /// <returns>Instance of asked type</returns>
        /// <exception cref="NotSupportedExceptio">Fires if asked type is not supported by current resository implementation</exception>
        T Create<T>() where T : class;

        /// <summary>
        /// Gets entity by the key
        /// </summary>
        /// <param name="key">key</param>
        /// <exception cref="ArgumentNullException">Fires if key is null</exception>
        /// <exception cref="InvalidOperationException">Fires if Entity was not initialized</exception>
        T Item<T, Key>(Key key)
            where T : class;

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        IQueryable<T> GetQuery<T>() where T : class;

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        IEnumerable<T> Enumerate<T>() where T : class;
    }
}
